package com.unitd.frame.mybatis.kit;

import com.unitd.frame.comm.utils.BeanUtils;
import com.unitd.frame.comm.utils.encrypt.MD5Utils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * @desc 缓存对象的key生成goongoon工具类
 * @filename CacheKeyKit.java
 * @copyright www.unitd.com
 * @author Hudan
 * @version 1.0
 * @date 2017/12/18
 */
public class CacheKeyKit {

	/**
	 * @desc 将缓存对象转换成字符串
	 * @param obj 缓存对象
	 * @return 字符串
	 */
	public static String toString(Object obj) {
		if (obj == null) return "_";
		if (isSimpleDataType(obj)) {
			return obj.toString();
		} else if (obj instanceof Collection) {
			String toString = obj.toString().replaceAll("\\s{0,}", "");
			return toString.length() > 32 ? MD5Utils.encrypt(toString) : toString;
		} else {
			String toString = ToStringBuilder.reflectionToString(obj, ToStringStyle.SHORT_PREFIX_STYLE);

			return toString.length() > 32 ? MD5Utils.encrypt(toString) : toString;
		}
	}

	/**
	 * @desc 生成缓存key
	 * @param prefix 缓存key的前缀
	 * @param args   缓存参数
	 * @return 缓存key
	 */
	public static String generate(String prefix, Object... args) {
		if(BeanUtils.isNull(args) || args.length==0) {
			return prefix;
		}

		StringBuilder keyBuilder = new StringBuilder(prefix);

		keyBuilder.append(":");
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < args.length; i++) {
			if (args[i] == null) {
				sb.append("_null");
			} else if (isSimpleDataType(args[i])) {
				sb.append(args[i].toString());
			} else if (args[i] instanceof Collection) {
				sb.append(args[i].toString().replaceAll("\\s{0,}", ""));
			} else {
				sb.append(ToStringBuilder.reflectionToString(args[i], ToStringStyle.SHORT_PREFIX_STYLE));
			}
			if (i < args.length - 1) sb.append("_");
		}
		String keyString = sb.length() > 32 ? MD5Utils.encrypt(sb.toString()) : sb.toString();
		keyBuilder.append(keyString);
		return keyBuilder.toString();
	}

	/**
	 * @desc 是否是基本数据类型
	 * @param object 缓存对象
	 * @return 是否是基本数据类型
	 */
	private static boolean isSimpleDataType(Object object) {
		Class<? extends Object> clazz = object.getClass();
		return
				(
						clazz.equals(String.class) ||
								clazz.equals(Character.class) ||
								clazz.equals(Byte.class) ||
								clazz.equals(Short.class) ||
								clazz.equals(Integer.class) ||
								clazz.equals(Long.class) ||
								clazz.equals(Float.class) ||
								clazz.equals(Double.class) ||
								clazz.equals(BigDecimal.class) ||
								clazz.equals(Boolean.class) ||
								clazz.equals(Date.class) ||
								clazz.isPrimitive()
				);
	}
	public static void main(String[] args) {
		List<Object> ids = new ArrayList<>();
		ids.add(1);
		ids.add("2ff ");
		ids.add(2);

		System.out.println(generate("demo_", ids));
		System.out.println(generate("demo_", ids));

		String[] arr = new String[]{"1", "b"};
		System.out.println(generate("demo_", arr));
	}
}
